import React from "react";
import {
  Table,
  Space,
  Button,
  Modal,
  Form,
  Input,
  Radio,
  Select,
  message,
} from "antd";
import type { TableColumnsType } from "antd";
import type { TablePaginationConfig } from "antd/es/table";
// import { UploadFile } from "antd/lib/upload/interface";
import type { FilterValue, SorterResult } from "antd/es/table/interface";
import { ColumnType, FilterConfirmProps } from "antd/lib/table/interface";
import { SearchOutlined } from "@ant-design/icons";
import Highlighter from "react-highlight-words";
import { useRequest } from "ahooks";
import { useSelector } from "react-redux";

import {
  RoleI,
  RoleUserI,
  RootStateI,
  UploadedFileI,
  UserI,
} from "../../types/system";
import {
  createUser,
  searchRoleList,
  searchUserList,
  updateUser,
} from "../../api/system";
import styles from "./index.module.less";
import { dayjs } from "../../App";
import { useLocation, useNavigate } from "react-router-dom";
import { testPasswordStrength } from "../../utils";
import { CustomResponse } from "../../api/http_class";

const UserManage = (): JSX.Element => {
  const location = useLocation();
  const navigate = useNavigate();
  const user: UserI | undefined = useSelector((state: RootStateI) => {
    return state.user;
  });
  const [showEditModal, setShowEditModal] = React.useState<boolean>(false);
  const [submitting, setSubmitting] = React.useState<boolean>(false);
  const [formDisabled] = React.useState<boolean>(false);
  // const [currentPage, setCurrentPage] = React.useState<number>(1);
  // const [pageSize, setPageSize] = React.useState<number>(20);
  // 总条目数为后台传来的，不能用收到的数据条目数计算
  const [totalCount, setTotalCount] = React.useState<number>(0);
  // const [sortField, setSortField] = React.useState<any>("createdAt");
  // const [sortOrder, setSortOrder] = React.useState<string | null | undefined>("descend");
  // const [filters, setFilters] = React.useState<Record<string, FilterValue | null>>();
  const [searchText, setSearchText] = React.useState("");
  const [fileUrl] = React.useState<string>("");
  const [selectedUploadedFile] = React.useState<UploadedFileI>();
  const [showPreviewModal, setShowPreviewModal] =
    React.useState<boolean>(false);
  const [userList, setUserList] = React.useState<UserI[]>([]);
  const [domainRoleList, setDomainRoleList] = React.useState<RoleI[]>([]);
  const searchInput = React.useRef<any>(null);
  const [userForm] = Form.useForm<UserI>();
  // const [importForm] = Form.useForm();

  const refImagePreview = React.useRef<HTMLImageElement>(null);

  const { loading, run } = useRequest(
    (paramsString: string) => searchUserList(paramsString),
    {
      manual: false,
      defaultParams: [location.search.replace(/^\?/, "")],
      onSuccess(resp: any, params: any) {
        console.log(params);
        setUserList(resp.data.data);
        setTotalCount(resp.data.totalCount);
      },
      onError(e: any, params: any) {
        message.error("获取数据失败");
      },
    }
  );

  // console.log(user);
  const params = {
    filters: [
      {
        "tenant.id": user.roleUsers.map(
          (item: RoleUserI) => item.role?.tenantId
        ),
      },
    ],
  };
  // console.log(JSON.stringify(params));
  useRequest((paramsString: string) => searchRoleList(paramsString), {
    manual: false,
    defaultParams: [JSON.stringify(params)],
    onSuccess(resp: any, params: any) {
      console.log(params);
      setDomainRoleList(resp.data.data);
      setTotalCount(resp.data.totalCount);
    },
    onError(e: any, params: any) {
      message.error("获取数据失败");
    },
  });

  type DataIndex = keyof UserI;
  const handleSearch = (
    selectedKeys: string[],
    confirm: (param?: FilterConfirmProps) => void,
    dataIndex: DataIndex
  ) => {
    // confirm触发TableChange动作
    setSearchText(selectedKeys[0]);
    // setSearchedColumn(String(dataIndex));
    confirm();
  };

  const handleReset = (clearFilters: () => void) => {
    clearFilters();
  };

  // const handleBeforeUploadFile = (file: File) => {
  // 	return false;
  // };

  const getColumnSearchProps: any = (
    dataIndex: DataIndex
  ): ColumnType<typeof columns> => ({
    filterDropdown: ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters,
      visible,
    }) => (
      <div style={{ padding: 8 }} onKeyDown={(e) => e.stopPropagation()}>
        <Input
          ref={searchInput}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0] as any}
          onChange={(e) =>
            setSelectedKeys(e.target.value ? [e.target.value] : [])
          }
          onPressEnter={() =>
            handleSearch(selectedKeys as string[], confirm, dataIndex)
          }
          style={{ marginBottom: 8, display: "block" }}
        />
        <Space>
          <Button
            type="primary"
            onClick={() =>
              handleSearch(selectedKeys as string[], confirm, dataIndex)
            }
            icon={<SearchOutlined />}
            size="small"
            style={{ width: 90 }}
          >
            搜索
          </Button>
          <Button
            onClick={() => clearFilters && handleReset(clearFilters)}
            size="small"
            style={{ width: 90 }}
          >
            重置
          </Button>
          <Button
            type="link"
            size="small"
            onClick={() => {
              confirm({ closeDropdown: false });
              setSearchText((selectedKeys as string[])[0]);
              // setSearchedColumn(dataIndex);
            }}
          >
            筛选
          </Button>
          <Button
            type="link"
            size="small"
            onClick={() => {
              visible = false;
            }}
          >
            关闭
          </Button>
        </Space>
      </div>
    ),
    filterIcon: (filtered: boolean) => (
      <SearchOutlined style={{ color: filtered ? "#1890ff" : undefined }} />
    ),
    onFilter: (value, record: any) => {
      if (!record[dataIndex]) {
        return false;
      } else {
        return record[dataIndex]
          .toString()
          .toLowerCase()
          .includes((value as string).toLowerCase());
      }
    },
    onFilterDropdownOpenChange: (visible) => {
      if (visible) {
        setTimeout(() => searchInput.current?.select(), 100);
      }
    },
    render: (value: any, record: any, index: number): React.ReactNode => {
      // console.log(value);
      // console.log(record);
      // console.log(searchedColumn);
      // console.log(dataIndex);
      // console.log(dataIndex.toString().split(".")[0]);
      // console.log(dataIndex.toString().split(".")[1]);
      // console.log(record[dataIndex.toString().split(".")[0]]);
      // console.log(record[index]);
      // console.log(record[dataIndex.toString().split(".")[0]][dataIndex.toString().split(".")[1]]);
      // console.log(typeof record[dataIndex.toString().split(".")[0]]);
      if (typeof record[dataIndex.toString().split(".")[0]] === "object") {
        // console.log(record[dataIndex.toString().split(".")[0]]);
        if (record[dataIndex.toString().split(".")[0]]) {
          return (
            <Highlighter
              highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
              searchWords={[searchText]}
              autoEscape
              textToHighlight={
                record &&
                record[dataIndex.toString().split(".")[0]] &&
                record[dataIndex.toString().split(".")[0]][
                  dataIndex.toString().split(".")[1]
                ]
                  ? record[dataIndex.toString().split(".")[0]][
                      dataIndex.toString().split(".")[1]
                    ].toString()
                  : ""
              }
            />
          );
        } else {
          return <span></span>;
        }
      } else {
        return (
          <Highlighter
            highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
            searchWords={[searchText]}
            autoEscape
            textToHighlight={
              record && record[dataIndex.toString().split(".")[0]]
                ? record[dataIndex.toString().split(".")[0]].toString()
                : ""
            }
          />
        );
      }
    },
  });

  const columns: TableColumnsType<UserI> = [
    {
      title: "用户名称",
      dataIndex: "username",
      width: "200px",
      ellipsis: true,
      key: "username",
      sorter: {
        compare: (a: UserI, b: UserI) => {
          return a.username.localeCompare(b.username);
        },
        multiple: 2,
      },
      render: (text) => <span>{text}</span>,
      ...getColumnSearchProps("username"),
    },
    {
      title: "邮箱",
      dataIndex: "email",
      width: "200px",
      ellipsis: true,
      key: "email",
      sorter: (a: UserI, b: UserI) => {
        return a.email.localeCompare(b.email);
      },
      render: (text) => <span>{text}</span>,
      ...getColumnSearchProps("email"),
    },
    {
      title: "用户电话",
      dataIndex: "cellphone",
      width: "200px",
      ellipsis: true,
      key: "cellphone",
      sorter: (a: UserI, b: UserI) => {
        return a.cellphone.localeCompare(b.cellphone);
      },
      render: (text) => <span>{text}</span>,
      ...getColumnSearchProps("cellphone"),
    },
    {
      title: "性别",
      dataIndex: "sex",
      width: "200px",
      ellipsis: true,
      key: "sex",
      sorter: (a: UserI, b: UserI) => {
        return a.sex.toString().localeCompare(b.sex.toString());
      },
      filters: [
        { text: "男", value: 1 },
        { text: "女", value: 2 },
      ],
      onFilter: (value: number, record: UserI) => record.sex === value,
      render: (text) => <span>{text}</span>,
    },
    {
      title: "是否激活",
      dataIndex: "isActive",
      width: "200px",
      ellipsis: true,
      key: "isActive",
      sorter: (a: UserI, b: UserI) => {
        return a.isActive.toString().localeCompare(b.isActive.toString());
      },
      filters: [
        { text: "是", value: true },
        { text: "否", value: false },
      ],
      onFilter: (value: boolean, record: UserI) => record.isActive === value,
      render: (value) => <span>{value ? "是" : "否"}</span>,
    },
    {
      title: "超级用户",
      dataIndex: "isSuperuser",
      width: "200px",
      ellipsis: true,
      key: "isSuperuser",
      sorter: (a: UserI, b: UserI) => {
        return a.isSuperuser.toString().localeCompare(b.isSuperuser.toString());
      },
      filters: [
        { text: "是", value: true },
        { text: "否", value: false },
      ],
      onFilter: (value: boolean, record: UserI) => record.isSuperuser === value,
      ...getColumnSearchProps("isSuperuser"),
      render: (value) => <span>{value ? "是" : "否"}</span>, // 放后面覆盖getColumnSearchProps中的render()
    },
    {
      title: "创建时间",
      dataIndex: "createdAt",
      width: "200px",
      ellipsis: true,
      key: "createdAt",
      sorter: {
        compare: (a: UserI, b: UserI) => {
          return dayjs(a.createdAt).valueOf() - dayjs(b.createdAt).valueOf();
        },
        multiple: 1,
      },
      render: (text) => {
        return <span>{dayjs(text).format("YYYY-MM-DD HH:mm:ss")}</span>;
      },
    },
    {
      title: "操作",
      dataIndex: "operation",
      width: "200px",
      ellipsis: true,
      fixed: "right" as const,
      key: "operation",
      render: (_: any, record: UserI) => (
        <Space>
          <Button onClick={handleEditUserClick.bind(this, record)} size="small">
            编辑
          </Button>
          {/* <Popconfirm
	        title="删除此项"
	        okText="删除"
	        cancelText="取消"
	        onConfirm={handleDeleteUserClick.bind(this, record)}
	      >
	        <Button size="small" danger>
	          删除
	        </Button>
	      </Popconfirm> */}
        </Space>
      ),
    },
  ];

  const handleEditUserClick = (record: UserI) => {
    console.log(record);
    const values = Object.assign({}, record, {
      roleIds: record.roleUsers.map((item: RoleUserI) => item.roleId),
    });
    userForm.setFieldsValue(values);
    setShowEditModal(true);
  };

  const handleAddClick = () => {
    userForm.resetFields();
    setShowEditModal(true);
  };

  const handleRoleUserChange = () => {
    console.log("handleRoleUserChange");
  };

  const handleEditModalOk = () => {
    userForm
      .validateFields()
      .then((values: UserI) => {
        console.log(values);
        setSubmitting(true);
        if (values.id) {
          updateUser(values).then(
            (res) => {
              // console.log(res);
              userForm.resetFields();
              setSubmitting(false);
              setShowEditModal(false);
              run(location.search.replace(/^\?/, ""));
            },
            (err: any) => {
              console.log(err);
              message.error(err.detail);
              setSubmitting(false);
              setShowEditModal(false);
            }
          );
        } else {
          createUser(values).then(
            (res) => {
              // console.log(res);
              userForm.resetFields();
              setSubmitting(false);
              setShowEditModal(false);
              run(location.search.replace(/^\?/, ""));
            },
            (err: any) => {
              console.log(err);
              message.error(err.detail);
              setSubmitting(false);
              setShowEditModal(false);
            }
          );
        }
      })
      .catch((err: any) => {
        console.log(err);
      });
  };

  const handleEditModalCancel = () => {
    setShowEditModal(false);
  };

  // const handleImportOk = () => {
  // 	importForm.validateFields().then((values: any) => {
  // 		console.log(values);
  // 		setSubmitting(true);
  // 		const formData = new FormData();
  // 		// 将全部数据转换为FormData格式
  // 		Object.keys(values).map((item) => {
  // 			// console.log(item);
  // 			if (item !== "fileList") {
  // 				formData.append(item, values[item]);
  // 			} else if (item === "fileList") {
  // 				if (values.fileList) {
  // 					values.fileList.fileList.forEach((element: UploadFile) => {
  // 						if (element.originFileObj) {
  // 							formData.append("files", element.originFileObj);
  // 						}
  // 					});
  // 				}
  // 			}
  // 			return 0;
  // 		});
  // 		request({
  // 			url: `/users/import/`,
  // 			method: "POST",
  // 			data: formData
  // 			// headers: { "Content-Type": "multipart/form-data" },
  // 		}).then(
  // 			(res) => {
  // 				console.log(res);
  // 				userForm.resetFields();
  // 				setSubmitting(false);
  // 				setShowImportModal(false);
  // 				message.success("数据导入成功");
  // 			},
  // 			(err: any) => {
  // 				console.log(err);
  // 				message.error(err.detail);
  // 				setSubmitting(false);
  // 			}
  // 		);
  // 	});
  // };

  // const handleImportCancel = () => {
  // 	setShowImportModal(false);
  // };

  // 表格条件改变时，将表格参数写到URL并根据表格条件重新获取数据
  const handleTableChange = (
    newPagination: TablePaginationConfig,
    newFilters: Record<string, FilterValue | null>,
    newSorters: SorterResult<UserI> | SorterResult<UserI>[]
  ) => {
    // console.log(newPagination);
    console.log(newFilters);
    // console.log(newSorters);
    // console.log(Array.isArray(newFilters));
    // console.log(Array.isArray(newFilters.sex));
    // console.log(JSON.stringify(newFilters));
    // console.log(JSON.stringify(newSorters));
    const params = new URLSearchParams();
    params.set("currentPage", newPagination.current?.toString() || "1");
    params.set("pageSize", newPagination.pageSize?.toString() || "10");

    params.set("filters", JSON.stringify(newFilters));
    params.set("sorters", JSON.stringify(newSorters));

    // console.log(`${location.pathname}?${params.toString()}`);
    navigate(`${location.pathname}?${params.toString()}`);
    // refreshUserList(params.toString());
    run(params.toString());
  };

  // 换成useRequest写法
  // const refreshUserList = React.useCallback((paramsString: string) => {
  // 	setLoadingUserList(true);
  // 	searchUserList(paramsString).then(
  // 		(res: any) => {
  // 			console.log(res);
  // 			setUserList(res.data.data);
  // 			// setTotalCount(res.data.totalCount);
  // 			setLoadingUserList(false);
  // 		},
  // 		(err: any) => {
  // 			console.log(err);
  // 			message.error(err.detail);
  // 			setLoadingUserList(false);
  // 		}
  // 	);
  // }, []);

  // React.useEffect(() => {
  // 	// console.log(location);
  // 	// 获取URL中的参数
  // 	// const urlSearchParams = new URLSearchParams(location.search);
  // 	// console.log(urlSearchParams);
  // 	refreshUserList(location.search.replace(/^\?/, ""));
  // }, [location, refreshUserList]);

  return (
    <div className={styles.table}>
      <div>
        <div className={styles.tableHeader}>
          <Space style={{ marginBottom: 16 }}>
            <Button onClick={handleAddClick} size="small">
              添加
            </Button>
          </Space>
          {/* <Space>
						<Button onClick={() => setShowImportModal(true)}>从Excel批量导入</Button>
					</Space> */}
        </div>
        <Modal
          title={"文件预览"}
          open={showPreviewModal}
          onOk={() => {
            setShowPreviewModal(false);
          }}
          onCancel={() => {
            setShowPreviewModal(false);
          }}
        >
          {selectedUploadedFile && (
            <img
              ref={refImagePreview}
              src={fileUrl}
              alt="图片预览"
              style={{ maxWidth: "100%" }}
            ></img>
          )}
        </Modal>
        <Table
          columns={columns}
          rowKey={(record: UserI) => record.id}
          dataSource={userList}
          expandable={{
            defaultExpandedRowKeys: ["0"],
          }}
          pagination={{
            // current: currentPage,
            total: totalCount,
            // pageSize: pageSize
          }}
          loading={loading}
          onChange={handleTableChange}
          scroll={{ x: 800, y: 600 }}
        ></Table>
      </div>
      <Modal
        title={userForm.getFieldValue("id") ? "修改用户" : "添加用户"}
        open={showEditModal}
        onOk={handleEditModalOk}
        onCancel={handleEditModalCancel}
        confirmLoading={submitting}
      >
        {/* 浏览器会寻找表单中的password输入框，自动填充之前的密码。
	      Chrome等浏览器autoComplete=off不起作用。放在这里起到蜜罐
	      的作用。但不能解决用户名自动填充和点击真实的密码框下拉列表的问题。
	      蜜罐不能用display: "none"或visibility: "hidden"隐藏，否则失效
	    */}
        <input
          type="password"
          style={{
            width: "1px",
            height: "1px",
            position: "absolute",
            border: "0px",
            padding: "0px",
          }}
        />
        <Form
          form={userForm}
          layout="vertical"
          name={"roleForm"}
          autoComplete="off"
          disabled={formDisabled}
          scrollToFirstError
        >
          <Form.Item
            name="id"
            label="id"
            hidden={!userForm.getFieldValue("id")}
            rules={[
              {
                required: false,
                message: "请输入id",
              },
            ]}
          >
            <Input disabled={true} />
          </Form.Item>
          <Form.Item
            name="username"
            label="用户名"
            hasFeedback
            rules={[
              {
                required: true,
                message: "请输入用户名",
              },
              {
                min: 3,
                message: "用户名最短3位",
              },
              {
                max: 32,
                message: "用户名最长32位",
              },
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            name="isActive"
            label="激活状态"
            rules={[
              {
                required: true,
                message: "请选择激活状态",
              },
            ]}
          >
            <Radio.Group
              options={[
                { label: "是", value: true },
                { label: "否", value: false },
              ]}
              optionType="button"
              buttonStyle="solid"
            />
          </Form.Item>
          <Form.Item
            name="isSuperuser"
            label="是否是超级用户"
            rules={[
              {
                required: true,
                message: "请选择是否是超级用户",
              },
            ]}
          >
            <Radio.Group
              options={[
                { label: "是", value: true },
                { label: "否", value: false },
              ]}
              optionType="button"
              buttonStyle="solid"
            />
          </Form.Item>
          <Form.Item
            name="password"
            dependencies={["id"]}
            label="用户密码"
            rules={[
              ({ getFieldValue }) => ({
                validator(_, value) {
                  // 无id说明是新用户，必须校验密码
                  if (getFieldValue("id") && !value) {
                    return Promise.resolve();
                  }
                  // 有密码时校验密码强度
                  if (value && value.length > 0) {
                    if (testPasswordStrength(value) < 3) {
                      return Promise.reject(
                        new Error(
                          "密码强度不够，建议至少6位，数字、大写字母、小写字母及其它字符至少包含3种"
                        )
                      );
                    }
                    return Promise.resolve();
                  } else {
                    return Promise.reject(new Error("请为用户设置初始密码"));
                  }
                },
              }),
            ]}
            hasFeedback
          >
            <Input.Password
              // autoComplete="off"无效，只使用new-password能解决Chrome自动填充问题
              // 但不解决点击密码框展示存的账号列表，蜜罐用于保险
              autoComplete="new-password"
            />
          </Form.Item>
          <Form.Item
            name="passwordAgain"
            label="再次输入用户密码"
            dependencies={["password", "id"]}
            hasFeedback
            rules={[
              ({ getFieldValue }) => ({
                validator(_, value) {
                  // 修改用户信息时允许不动密码
                  if (
                    getFieldValue("id") &&
                    getFieldValue("password") === "" &&
                    value === ""
                  ) {
                    return Promise.resolve();
                  }
                  if (!value || getFieldValue("password") === value) {
                    return Promise.resolve();
                  }
                  return Promise.reject(new Error("两次输入的密码不匹配"));
                },
              }),
            ]}
          >
            <Input.Password
              // autoComplete="off"无效，只使用new-password能解决Chrome自动填充问题
              // 但不解决点击密码框展示存的账号列表，蜜罐用于保险
              autoComplete="new-password"
            />
          </Form.Item>
          <Form.Item
            label="角色"
            name="roleIds"
            rules={[{ required: true, message: "请选择用户角色" }]}
          >
            <Select
              mode="multiple"
              style={{ width: "100%" }}
              filterOption={(input, option) => {
                return (
                  (option?.py ?? "").toString().toLowerCase().includes(input) ||
                  (option?.pinyin ?? "")
                    .toString()
                    .toLowerCase()
                    .includes(input) ||
                  (option?.children ?? "")
                    .toString()
                    .toLowerCase()
                    .includes(input)
                );
              }}
              onChange={handleRoleUserChange}
            >
              {domainRoleList.map((item: RoleI) => {
                return (
                  <Select.Option
                    value={item.id}
                    key={item.id}
                    pinyin={item.pinyin}
                    py={item.py}
                  >
                    {item.name}
                  </Select.Option>
                );
              })}
            </Select>
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default UserManage;
